package ruide_info_mvc.base.core.bean_core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import ruide_info_mvc.base.contoller.BaseContoller;
import ruide_info_mvc.base.core.aop.ICustomAop;
import ruide_info_mvc.base.core.aop.ICustomAssistAop;
import ruide_info_mvc.base.core.ioc.CustomIoc;
import ruide_info_mvc.base.model.request.BaseRequestBean;
import ruide_info_mvc.base.model.response.BaseResponseBean;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @ClassName AbstractBeanInvokeCore
 * @Author wangBo
 * @Date 2019/7/21 0021 上午 10:26
 * @Version 1.0
 */
public abstract class AbstractBeanInvokeCore implements IBeanInvokeCore , ICustomAssistAop , InitializingPostBean {

    protected final Logger logger = LoggerFactory.getLogger(BaseContoller.class);

    @Autowired
    private HttpServletRequest request;

    protected ICustomAop customAop;

    public BaseResponseBean invoke(BaseRequestBean baseRequestBean, MultipartFile[] files) throws Exception {
        BaseResponseBean baseResponseBean = new BaseResponseBean();
        Class clazz = null;
        Object beanObj = null;
        try {
            afterPropertiesSet();
            beanObj = CustomIoc.getApplicationContext().getBean(request.getParameter(serviceName));
            clazz = CustomIoc.getApplicationContext().getBean(request.getParameter(serviceName)).getClass();
        } catch (BeansException e) {
            logger.error("" , e);
        }
        try {
            Method[] methodArray = clazz.getDeclaredMethods();
            for (Method met : methodArray) {
                if (met.getName().equals(request.getParameter(methodName))) {
                    baseResponseBean = this.invoke_(beanObj , clazz , met , baseRequestBean , files);
                }
            }
        } catch (Exception e) {
            logger.error("" , e);
            throw e;
        }
        return baseResponseBean;
    }

    public BaseResponseBean invoke_(Object beanObj,Class clasz,Method method,BaseRequestBean baseRequestBean, MultipartFile[] files) throws Exception {
        BaseResponseBean baseResponseBean;
        Object [] paramsArray = new Object[]{baseRequestBean , files};
        this.before(clasz , method , paramsArray);
        baseResponseBean = invoke_(beanObj , method , baseRequestBean , files);
        this.after(clasz , method , paramsArray,baseRequestBean);
        return baseResponseBean;
    }

    @Override
    public void before(Object obj, Method method, Object [] params) {
        if (null != customAop)
            customAop.beforeAdvice(obj,method,params);
    }

    @Override
    public void after(Object obj, Method method, Object [] params , Object returnValue) {
        if (null != customAop)
            customAop.afterAdvice(obj,method,params,returnValue);
    }

    protected abstract BaseResponseBean invoke_(Object obj , Method method, BaseRequestBean baseRequestBean, MultipartFile[] files) throws Exception;

    private final String serviceName = "_serviceName";

    private final String methodName = "_methodName";
}
